package es.wtestgen.services;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Transaction;
import org.hibernate.classic.Session;
import org.hibernate.criterion.Restrictions;

import es.wtestgen.bean.profesor.AlumnoForm;
import es.wtestgen.domain.Alumno;
import es.wtestgen.domain.Asignatura;
import es.wtestgen.domain.ExamenResuelto;
import es.wtestgen.util.DniDuplicadoException;
import es.wtestgen.util.HibernateUtil;
import es.wtestgen.util.NombreUsuaException;

public class AlumnoDAO {
	
	private static final Log log = LogFactory.getLog(AlumnoDAO.class);
	
	public AlumnoDAO(){
		
	}
	
	
	public boolean eliminar(int codAlum){
		Transaction tx = null;
		Session session = HibernateUtil.currentSession();
		boolean eliminado = false;
		try{			
			tx = session.beginTransaction();
			Alumno alumno = (Alumno)session.get(Alumno.class, codAlum);
			//Set<Asignatura> asignaturas = alumno.getAsignaturas();
			AsignaturaDAO asignaturaDao = new AsignaturaDAO();
			ExamenResueltoDAO examenResuDao = new ExamenResueltoDAO();
			List<Asignatura> asignaturas =  (List<Asignatura>)asignaturaDao.findAsignaturasAlumno(alumno);
			
			if(asignaturas != null && asignaturas.size() > 0){
				for (Iterator iterator = asignaturas.iterator(); iterator.hasNext();) {
					Asignatura asignatura = (Asignatura) iterator.next();
					if(asignatura.getAlumnos().contains(alumno)){
						asignatura.getAlumnos().remove(alumno);		
						
					}
				}				
			}
			
			List<ExamenResuelto> examenesResu = (List<ExamenResuelto>)examenResuDao.findByAlumno(alumno);
			
			if(examenesResu != null && examenesResu.size() > 0){
				for (Iterator iterator = examenesResu.iterator(); iterator.hasNext();) {
					ExamenResuelto examenResu = (ExamenResuelto) iterator.next();
					if(String.valueOf(examenResu.getAlumno().getCodAlum()).equals(String.valueOf(alumno.getCodAlum()))){
						
						Session session2 = HibernateUtil.currentSession();
						Transaction tx2 = null;
						try{
							tx2 = session2.beginTransaction();
							
							ExamenResuelto examResu = (ExamenResuelto)session2.get(ExamenResuelto.class, examenResu.getCodExamResu());
							
							session2.delete(examResu); 
							
							tx2.commit();						
						}catch(Exception e){
							try{
								tx2.rollback();
								e.printStackTrace();
							}catch(Exception e2){
								e2.printStackTrace();								
							}
						}						
						///examenResuDao.eliminar(examenResu.getCodExamResu());						
					}
				}		
			}
			
			
			session.delete(alumno);
			tx.commit();
			eliminado = true;
		}catch(Exception e){
			try{
				tx.rollback();
			}catch(Exception e2){
				e2.printStackTrace();
			}
		}finally{
				HibernateUtil.closeSession();
		}
		return eliminado;
	}
	
	
	public boolean eliminarAlumnoDeAsignatura(int codAlum,int codAsig){
		Transaction tx = null;
		Session session = HibernateUtil.currentSession();
		boolean eliminado = false;
		try{			
			tx = session.beginTransaction();
			Alumno alumno = (Alumno)session.get(Alumno.class, codAlum);
			Asignatura asignatura = (Asignatura)session.get(Asignatura.class, codAsig);
			Set<Alumno> alumnos = (Set<Alumno>)asignatura.getAlumnos();//.remove(alumno);
			for (Iterator iterator = alumnos.iterator(); iterator.hasNext();) {
				Alumno a = (Alumno) iterator.next();
				if(a.getCodAlum() == alumno.getCodAlum()){
					alumnos.remove(alumno);
					break;
				}				
			}
			asignatura.setAlumnos(alumnos);
			session.saveOrUpdate(asignatura);
			tx.commit();
			eliminado = true;
		}catch(Exception e){
			try{
				tx.rollback();
				e.printStackTrace();
			}catch(Exception e2){
				e2.printStackTrace();
			}
		}finally{
				HibernateUtil.closeSession();
		}
		return eliminado;
	}
	
		
	public List findAll(){
		List lista = new ArrayList();
		Criteria criteria = null;
		
		try{
			Session session = HibernateUtil.currentSession();
			criteria = session.createCriteria(Alumno.class);				
			lista = criteria.list();		
		}catch(HibernateException e){
			log.error("_____Error al obtener la todos los registros de la clase Alumno",e);
			e.printStackTrace();
			throw new HibernateException(e);						
		}	
		return lista;
	}
	
	
	public List findById(String cod){
		List lista = new ArrayList();
		Criteria criteria = null;
		int id = Integer.parseInt(cod);
		
		try{
			Session session = HibernateUtil.currentSession();
			criteria = session.createCriteria(Alumno.class);				
			criteria.add(Restrictions.eq("codAlum", id));
			lista = criteria.list();		
		}catch(HibernateException e){
			log.error("_____Error al obtener el registro de la clase Alumno con id: " + cod,e);
			e.printStackTrace();
			throw new HibernateException(e);						
		}	
		return lista;
	}
	
	public List findByDni(String dni){
		List lista = new ArrayList();
		Criteria criteria = null;
		
		try{
			Session session = HibernateUtil.currentSession();
			criteria = session.createCriteria(Alumno.class);				
			criteria.add(Restrictions.eq("dni", dni));
			lista = criteria.list();		
		}catch(HibernateException e){
			log.error("_____Error al obtener el registro de la clase Alumno con dni: " + dni,e);
			throw new HibernateException(e);						
		}	
		return lista;	
	}
	
	
	public List findByNombreUsua(String nombreUsua){
		List lista = new ArrayList();
		Criteria criteria = null;
		
		try{
			Session session = HibernateUtil.currentSession();
			criteria = session.createCriteria(Alumno.class);				
			criteria.add(Restrictions.eq("nombreUsua", nombreUsua));
			lista = criteria.list();		
		}catch(HibernateException e){
			log.error("_____Error al obtener el registro de la clase Alumno con nombre de usuario: " + nombreUsua,e);
			throw new HibernateException(e);						
		}	
		return lista;
	}
	
	
	public List findByParameters(AlumnoForm alumnoForm){
		List lista = new ArrayList();
		Criteria criteria = null;
		
		try{
			Session session = HibernateUtil.currentSession();
			criteria = session.createCriteria(Alumno.class);				
			
			if(alumnoForm.getApellidos() != null && !"".equals(alumnoForm.getApellidos())){
				criteria.add(Restrictions.like("apellidos","%" + alumnoForm.getApellidos() + "%"));
			}
			if(alumnoForm.getDni() != null && !"".equals(alumnoForm.getDni())){
				criteria.add(Restrictions.like("dni","%" + alumnoForm.getDni() + "%"));				
			}
			if(alumnoForm.getEmail() != null && !"".equals(alumnoForm.getEmail())){
				criteria.add(Restrictions.like("email","%" + alumnoForm.getEmail() + "%"));				
			}
			if(alumnoForm.getNombre() != null && !"".equals(alumnoForm.getNombre())){
				criteria.add(Restrictions.like("nombre","%" + alumnoForm.getNombre() + "%"));				
			}
			if(alumnoForm.getTelefono() != null && !"".equals(alumnoForm.getTelefono())){
				criteria.add(Restrictions.like("telefono","%" + alumnoForm.getTelefono() + "%"));				
			}
			if(alumnoForm.getNombreUsua() != null && !"".equals(alumnoForm.getNombreUsua())){
				criteria.add(Restrictions.like("nombreUsua","%" + alumnoForm.getNombreUsua() + "%"));				
			}			
			
			lista = criteria.list();		
		}catch(HibernateException e){
			log.error("_____Error al obtener los registros de la clase Alumno para los parametros de busquedas." ,e);
			throw new HibernateException(e);						
		}	
		return lista;
	}
	
	
	public Set findAlumnosAsignatura(Asignatura asignatura){
		Set alumnos = new HashSet();
		
		try{
			Session session = HibernateUtil.currentSession();
			
			Asignatura asig = (Asignatura)session.get(Asignatura.class, asignatura.getCodAsig());
			
			alumnos = asig.getAlumnos();

		}catch(HibernateException e){
			log.error("_____Error al obtener los alumnos de la asignatura: "+ asignatura.getNombreAsig() ,e);
			throw new HibernateException(e);						
		}	
		
		return alumnos;
		
	}
	
	
	public boolean guardarAlumnoEnAsignatura(Alumno alum,String codAsig) throws NombreUsuaException,DniDuplicadoException{
		Transaction tx = null;
		Session session = HibernateUtil.currentSession();
		List<Alumno> alumnoDni = new ArrayList<Alumno>();
		List<Alumno> alumnos = new ArrayList<Alumno>();
		Alumno alumno = null;
		Asignatura asignatura = null;
		boolean guardado = false;
		boolean nombreUsuaRepetido = false;		
		try{			
			tx = session.beginTransaction();
			session.clear();
			//session.flush();
			asignatura = (Asignatura)session.get(Asignatura.class,Integer.parseInt(codAsig));
			
			alumnoDni = findByDni(alum.getDni());
			if(alumnoDni.size() == 1 && alum.getCodAlum() != -1){				
				alumno = (Alumno)session.get(Alumno.class, alumnoDni.get(0).getCodAlum());
			}else if(alumnoDni.size() >= 1 && alum.getCodAlum() == -1){
				guardado = false;				
				throw new DniDuplicadoException("____ADR: El Dni del alumno a insertar ya se encuentra en el sistema.");				
			}else{
				alumno = alum;	
				alumnos = findByNombreUsua(alumno.getNombreUsua());
				if(alumnos.size() > 0){
					nombreUsuaRepetido = true;
				}			
			}
			
			if(nombreUsuaRepetido){
				guardado = false;	
				throw new NombreUsuaException("____ADR: El Nombre de Usuario del alumno a insertar ya se encuentra en el sistema.");
			}else{
				alumno.setApellidos(alum.getApellidos());
				alumno.setDni(alum.getDni());
				alumno.setEmail(alum.getEmail());
				alumno.setNombre(alum.getNombre());
				alumno.setTelefono(alum.getTelefono());
				alumno.setNombreUsua(alum.getNombreUsua());
				alumno.setPwdUsua(alum.getPwdUsua());				
				
				alumno.getAsignaturas().add(asignatura);
				
				session.saveOrUpdate(alumno);
				tx.commit();
				
				Session session2 = HibernateUtil.currentSession();
				Transaction tx2 = null;
				asignatura = (Asignatura)session2.get(Asignatura.class,asignatura.getCodAsig());
				try{
					tx2 = session2.beginTransaction();					
					alumno.getAsignaturas().add(asignatura);
					
					session2.save(asignatura);
					
					tx2.commit();						
				}catch(Exception e){
					try{
						tx2.rollback();
						e.printStackTrace();
					}catch(Exception e2){
						e2.printStackTrace();
					}
				}
								
				guardado = true;				
			}
			
		}catch(HibernateException e){
			try{
				tx.rollback();
				e.printStackTrace();
			}catch(Exception e2){
				e2.printStackTrace();
			}
		}finally{
				HibernateUtil.closeSession();
		}
		return guardado;
	}
	
	
	public boolean guardarAlumnoExistenteEnAsignatura(Alumno alum,String codAsig){
		Transaction tx = null;
		Session session = HibernateUtil.currentSession();
		List<Alumno> alumnoDni = new ArrayList<Alumno>();
		Alumno alumno = null;
		Asignatura asignatura = null;
		boolean guardado = false;
		try{			
			tx = session.beginTransaction();
			session.clear();
			//session.flush();
			asignatura = (Asignatura)session.get(Asignatura.class,Integer.parseInt(codAsig));
			
			alumno = (Alumno)session.get(Alumno.class, alum.getCodAlum());				
			
			alumno.getAsignaturas().add(asignatura);
			
			session.save(alumno);
			tx.commit();
			
			Session session2 = HibernateUtil.currentSession();
			Transaction tx2 = null;
			try{
				tx2 = session2.beginTransaction();
				
				//alumno = (Alumno)session.get(Alumno.class, alum.getCodAlum());	
				asignatura.getAlumnos().add(alumno);
				session2.save(asignatura);
				//session2.update(preg); 
				
				tx2.commit();						
			}catch(Exception e){
				try{
					tx2.rollback();
					e.printStackTrace();
				}catch(Exception e2){
					e2.printStackTrace();
				}
			}			
			
			guardado = true;
		}catch(Exception e){
			try{
				tx.rollback();
				e.printStackTrace();
			}catch(Exception e2){
				e2.printStackTrace();
			}
		}finally{
				HibernateUtil.closeSession();
		}
		return guardado;
	}
	

}
